package org.spindle.dungeon;

import org.newdawn.slick.geom.Rectangle;
import org.spindle.dungeon.entities.GeneralEntity;

import java.util.*;

public class EntityManager {


    private static EntityManager instance = new EntityManager();

    private List<GeneralEntity> entities = new ArrayList<GeneralEntity>();

    private List<GeneralEntity> add = new ArrayList<GeneralEntity>();
    private List<GeneralEntity> remove = new ArrayList<GeneralEntity>();


    public boolean addFlag = true;

    private EntityManager() {

    }

    public static EntityManager getInstance() {
        return instance;
    }

    public void registerEntity(GeneralEntity entity) {
        if (addFlag) {
            entities.add(entity);
            sortList();
        }
        else
            add.add(entity);
    }

    public void removeEntity(GeneralEntity entity) {
        if (addFlag)
            entities.remove(entity);
        else
            remove.add(entity);
    }

    public void processAdditions() {
        addFlag = true;
        boolean added = false;
        for (GeneralEntity ent : add) {
            entities.add(ent);
            added = true;
        }
        for (GeneralEntity ent : remove) {
            entities.remove(ent);
        }
        add.clear();
        remove.clear();
        if (added) {
            sortList();
        }
    }

    private void sortList() {
        Collections.sort(entities, new Comparator<GeneralEntity>() {
            @Override
            public int compare(GeneralEntity o1, GeneralEntity o2) {
                return o2.layer-o1.layer;
            }
        });
    }


    public synchronized List<GeneralEntity> getEntities() {
        return entities;
    }

    public boolean canMove(GeneralEntity ent, int x, int y) {
        boolean canMove = true;
        if (ent.x + x < 0 || ent.x + x > Constants.STAGE_WIDTH || ent.y + y < 0 || ent.y + y > Constants.STAGE_HEIGHT) {
            canMove = false;
        } else {
            Rectangle entRect = new Rectangle(ent.x + x+ent.offsetHitboxX, ent.y + y+ent.offsetHitboxY, ent.hitBoxWidth, ent.hitBoxHeight);
            Rectangle nextRect;
            for (GeneralEntity entity : entities) {
                if (entity.collidable && entity != ent) {
                    nextRect = new Rectangle(entity.x, entity.y, Constants.TILE_SIZE, Constants.TILE_SIZE);
                    if (entRect.intersects(nextRect)) {
                        canMove = false;
                        break;
                    }
                }
            }
        }
        return canMove;
    }

    public  List<GeneralEntity> returnEntitiesAt(GeneralEntity ent, int x, int y) {
        List<GeneralEntity> entityList = null;

        Rectangle entRect = new Rectangle(ent.x + x+ent.offsetHitboxX, ent.y + y+ent.offsetHitboxY, ent.hitBoxWidth, ent.hitBoxHeight);
        Rectangle nextRect;
        for (GeneralEntity entity : entities) {
            if (entity != ent) {
                nextRect = new Rectangle(entity.x, entity.y, Constants.TILE_SIZE, Constants.TILE_SIZE);
                if (entRect.intersects(nextRect)) {
                    if (entityList == null) {
                        entityList = new ArrayList<GeneralEntity>();
                    }
                    entityList.add(entity);
                }
            }
        }

        return entityList;
    }


}
